/* kiko@idiospace.com 2020.01.20 */

#ifndef DataBuffer_HPP
#define DataBuffer_HPP

#include <chrono>
#include <exception>
#include <iostream>
#include <memory>
#include <mutex>
#include <queue>

#include "easylogging++.h"

using namespace std::chrono_literals;

namespace hnurm
{
    template<typename DataType>
    class DataBuffer
    {
    public:
        DataBuffer() = default;

        ~DataBuffer() = default;

        // 获取数据
        bool Get(DataType &data);

        // 更新数据
        bool Update(const DataType &data);

    private:
        DataType data_buf;  // 数据缓冲区
        std::timed_mutex mtx;  // 互斥锁
        bool updated_flag = false;  // 更新标志
    };// class DataBuffer

    template<class DataType>
    bool DataBuffer<DataType>::Get(DataType &data)
    {
        if (mtx.try_lock_for(2ms))
        {
            if(!updated_flag)
            {
                mtx.unlock();
                return false;
            }
            LOG(WARNING) << "Success to lock in GET, UPDATED";
            data = data_buf;
            updated_flag = false;
            mtx.unlock();
            return true;
        }
        LOG(WARNING) << "Failed to lock in GET";
        return false;
    }

    template<class DataType>
    bool DataBuffer<DataType>::Update(const DataType &data)
    {
        if (mtx.try_lock_for(2ms))
        {
            LOG(WARNING) << "Success to lock in UPDATE";
            data_buf = data;
            updated_flag = true;
            mtx.unlock();
            return true;
        }
        LOG(WARNING) << "Failed to lock in UPDATE";
        return false;
    }
}// namespace hnurm


#endif// DataBuffer_HPP
